package mobi.hami.huapin.config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import org.springframework.cache.interceptor.KeyGenerator;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * redis 单机配置
 *
 * @author 阿飞 jijunjian@hami.mobi
 * @date 2018/8/27 17:20
 */
@Configuration
@EnableCaching
public class AloneRedisConfig {

    @Autowired
    private AloneRedis jedisConfig;


    @Bean
    public RedisConnectionFactory redisConnectionFactory()
    {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();

        if ( jedisConfig.port > 0) //port=0 表示用集群
        {
            jedisConnectionFactory.setHostName(jedisConfig.host);
            jedisConnectionFactory.setPort(jedisConfig.port);

        }
        else //集群
        {
            RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
            List<RedisNode> nodeList = new ArrayList<>();
            String[] nodelist = jedisConfig.clusternodes.split(",");
            for (String node:nodelist ) {
                String[] ipPortPair = node.split(":");
                nodeList.add(new RedisNode(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
            }
            clusterConfiguration.setClusterNodes(nodeList);
            jedisConnectionFactory = new JedisConnectionFactory(clusterConfiguration);


        }

        jedisConnectionFactory.setDatabase(jedisConfig.database);
        if ( jedisConfig.password.length() > 0)
        {
            jedisConnectionFactory.setPassword(jedisConfig.password);
        }


        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(jedisConfig.maxIdle);
        poolConfig.setMinIdle(jedisConfig.minIdle);
        poolConfig.setMaxTotal(jedisConfig.maxActive);
        poolConfig.setMaxWaitMillis(jedisConfig.maxWait);
        poolConfig.setTestOnBorrow(false);
        poolConfig.setTestOnReturn(false);

        jedisConnectionFactory.setPoolConfig(poolConfig);


        return  jedisConnectionFactory;
    }

    @Bean
    public RedisTemplate<String , String> redisTemplate(JedisConnectionFactory jedisConnectionFactory)
    {

        RedisTemplate<String ,String> rt = new RedisTemplate<String, String>();
        rt.setConnectionFactory(jedisConnectionFactory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer(String.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisSerializer rs=new StringRedisSerializer();
        rt.setKeySerializer(rs);
        rt.setValueSerializer(jackson2JsonRedisSerializer);
        rt.setHashKeySerializer(rs);
        rt.setHashValueSerializer(jackson2JsonRedisSerializer);
       // rt.afterPropertiesSet();

        rt.setEnableTransactionSupport(true);

        return  rt;

    }

    @Bean
    public CacheManager cacheManager(RedisTemplate<String , String> redisTemplate)
    {
        RedisCacheManager cacheManager= new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(60*60*6); //默热6小时
        return  cacheManager;
    }

    @Bean(name = "firstParamKeyGenerator")
    public KeyGenerator firstParamKeyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {

                //logger.info("firstParamKeyGenerator:"+ target.getClass().getName()+"  method="+method.getName());

                // todo 这里要传入方法名+类名

                StringBuilder sb = new StringBuilder();
                sb.append(params[0].toString());
                return sb.toString();
            }
        };
    }
}
